package max.ta.util.file;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;

import org.apache.log4j.Logger;

public class FileHelper {

    private static final Logger logger = Logger.getLogger(FileHelper.class);

    // -------------------------------------------------------------------------------------
    // List
    // -------------------------------------------------------------------------------------
    public static List<File> getFiles(File dir) {
	return getFiles(dir, null);
    }

    public static List<File> getFiles(File dir, FileFilter filter) {
	if (!dir.isDirectory()) {
	    throw new IllegalArgumentException(dir.getAbsolutePath() + " is not directory");
	}
	File[] foundFiles = filter != null ? dir.listFiles(filter) : dir.listFiles();
	List<File> files = new ArrayList<File>();
	if (foundFiles != null && foundFiles.length > 0) {
	    files.addAll(Arrays.asList(foundFiles));
	}
	logger.info(">>> Number of valid files " + files.size() + " found in : " + dir.getAbsolutePath());
	return files;
    }

    // -------------------------------------------------------------------------------------
    // READ
    // -------------------------------------------------------------------------------------
    public static String read(File file) throws IOException {
	if (file == null || !file.exists() || !file.isFile()) {
	    throw new IllegalArgumentException(" The file does not exist");
	}
	BufferedReader in = null;
	try {
	    in = new BufferedReader(new FileReader(file));
	    String line;
	    StringBuilder bf = new StringBuilder();
	    while ((line = in.readLine()) != null) {
		bf.append(line + "\n");
	    }
	    return bf.toString();
	} finally {
	    if (in != null) {
		in.close();
	    }
	}
    }

    // -------------------------------------------------------------------------------------
    // CREATE
    // -------------------------------------------------------------------------------------
    public static void createDir(String filePath) throws IOException {
	if (filePath == null || filePath.trim().length() == 0) {
	    throw new IOException("Invalid/empty directory path");
	}
	createDir(new File(filePath));
    }

    public static void createDir(File file) throws IOException {
	if (file != null && !file.exists()) {
	    logger.info("creating folder : " + file.getAbsolutePath());
	    if (!file.mkdirs()) {
		throw new IOException(file.getAbsolutePath() + " directory was not created");
	    }
	}
    }

    public static void createFile(String filePath) throws IOException {
	if (filePath == null || filePath.trim().length() == 0) {
	    throw new IOException("Invalid/empty file path");
	}
	createFile(new File(filePath));
    }

    public static void createFile(File file) throws IOException {
	if (file != null && !file.exists()) {
	    logger.info("creating file : " + file.getAbsolutePath());
	    if (!file.createNewFile()) {
		throw new IOException(file.getAbsolutePath() + " file was not created");
	    }
	}
    }

    // -------------------------------------------------------------------------------------
    // WRITE
    // -------------------------------------------------------------------------------------
    public static File writeText(String content, String filePath) throws IOException {
	File file = new File(filePath);
	return writeText(content, file);
    }

    public static File writeText(String content, File file) throws IOException {
	BufferedWriter out = null;
	try {
	    createFile(file);
	    out = new BufferedWriter(new FileWriter(file));
	    out.write(content);
	} finally {
	    out.close();
	}
	return file;
    }

    // -------------------------------------------------------------------------------------
    // COPY
    // -------------------------------------------------------------------------------------
    private static final int BUFFER_SIZE = 1024;

    public static void copyfile(String source, String destination) throws IOException {
	copyfile(new File(source), new File(destination));
    }

    public static boolean copyfile(File source, File destination) throws IOException {
	InputStream in = null;
	OutputStream out = null;
	try {
	    in = new FileInputStream(source);
	    out = new FileOutputStream(destination);
	    byte[] buf = new byte[BUFFER_SIZE];
	    int len;
	    while ((len = in.read(buf)) > 0) {
		out.write(buf, 0, len);
	    }
	    logger.info(source.getAbsoluteFile() + " file  copied into " + destination.getAbsolutePath());
	} finally {
	    if (in != null) {
		in.close();
	    }
	    if (out != null) {
		out.close();
	    }
	}
	return destination.exists() && destination.length() == source.length();
    }

    // -------------------------------------------------------------------------------------
    // Archive
    // -------------------------------------------------------------------------------------
    public static String createArchivePath(String parentDir) {
	Calendar calendar = Calendar.getInstance();
	String year = String.valueOf(calendar.get(Calendar.YEAR));
	String month = String.format("%02d", (calendar.get(Calendar.MONTH) + 1));
	String day = String.format("%02d", calendar.get(Calendar.DAY_OF_MONTH));
	return parentDir + year + "/" + month + "/" + day;
    }
}
